package com.zzyl.nursing.service.impl;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdcardUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.StringUtils;
import com.zzyl.framework.ai.AiInvoker;
import com.zzyl.nursing.domain.HealthAssessment;
import com.zzyl.nursing.dto.HealthAssessmentDto;
import com.zzyl.nursing.mapper.HealthAssessmentMapper;
import com.zzyl.nursing.service.IHealthAssessmentService;
import com.zzyl.nursing.vo.HealthReportVo;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

import static java.nio.charset.StandardCharsets.UTF_8;

/**
 * 健康评估Service业务层处理
 *
 * @author Nuyoah
 * @date 2025-05-20
 */
@Service
public class HealthAssessmentServiceImpl extends ServiceImpl<HealthAssessmentMapper, HealthAssessment> implements IHealthAssessmentService
{
    @Autowired
    private HealthAssessmentMapper healthAssessmentMapper;

    /**
     * 查询健康评估
     *
     * @param id 健康评估主键
     * @return 健康评估
     */
    @Override
    public HealthAssessment selectHealthAssessmentById(Long id)
    {
        return getById(id);
    }

    /**
     * 查询健康评估列表
     *
     * @param healthAssessment 健康评估
     * @return 健康评估
     */
    @Override
    public List<HealthAssessment> selectHealthAssessmentList(HealthAssessment healthAssessment)
    {
        return healthAssessmentMapper.selectHealthAssessmentList(healthAssessment);
    }
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private AiInvoker aiInvoker;

    /**
     * 新增健康评估
     *
     * @param dto 健康评估
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long insertHealthAssessment(HealthAssessmentDto dto)
    {
        //0.校验参数
        if(StringUtils.isBlank(dto.getElderName()) || "null".equals(dto.getElderName())) {
            throw new BaseException("姓名参数非法");
        }
        if(StringUtils.isBlank(dto.getIdCard()) || "null".equals(dto.getIdCard())) {
            throw new BaseException("身份证号参数非法");
        }
        if(StringUtils.isBlank(dto.getPhysicalExamInstitution()) || "null".equals(dto.getPhysicalExamInstitution())) {
            throw new BaseException("检测机构名称参数非法");
        }
        if(StringUtils.isBlank(dto.getPhysicalReportUrl()) || "null".equals(dto.getPhysicalReportUrl())) {
            throw new BaseException("检测报告的URL地址参数非法");
        }

        //1.从Redis中获取体检报告的Pdf内容
        String pdfText = (String) redisTemplate.opsForHash().get(CacheConstants.HEALTH_ASSESSMENT_TEXT_KEY, dto.getIdCard());

        //2.从Resource下读取prompt.txt文件
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("prompt.txt");
        String template = IoUtil.read(inputStream, UTF_8);

        //3.组织prompt提示词
        String prompt = template.replace("prompt", pdfText);

        //4.调用百度千帆大模型API单轮对话接口
        String qianFanChat = aiInvoker.invokerQianFanChat(prompt);
        if (StringUtils.isBlank(qianFanChat)){
            throw new BaseException("调用千帆大模型接口失败");
        }

        //5.解析JSON字符串为HealthReportVo对象
        HealthReportVo healthReportVo = JSON.parseObject(qianFanChat, HealthReportVo.class);

        //6.向数据库中添加数据,新增健康评估表数据
        long id  = saveHealthAssessment(dto, healthReportVo);

        //7.添加成功后删除Redis缓存
        redisTemplate.opsForHash().delete(CacheConstants.HEALTH_ASSESSMENT_TEXT_KEY, dto.getIdCard());

        //8.返回表的主键ID
        return id;

    }

    /**
     *新增健康评估表数据
     * @param dto
     * @param healthReportVo
     * @return
     */
    @NotNull
    private Long saveHealthAssessment(HealthAssessmentDto dto, HealthReportVo healthReportVo) {
        HealthAssessment healthAssessment = new HealthAssessment();
        healthAssessment.setElderName(dto.getElderName());//老人姓名
        healthAssessment.setIdCard(dto.getIdCard());//老人身份证号
        healthAssessment.setPhysicalExamInstitution(dto.getPhysicalExamInstitution());//体检机构
        healthAssessment.setPhysicalReportUrl(dto.getPhysicalReportUrl());//体检报告URL链接
        healthAssessment.setBirthDate(IdcardUtil.getBirthDate(dto.getIdCard()).toLocalDateTime());//出生日期
        healthAssessment.setAge(IdcardUtil.getAgeByIdCard(dto.getIdCard()));//老人年龄
        healthAssessment.setGender(IdcardUtil.getGenderByIdCard(dto.getIdCard()));//性别(0:男,1:女)
        double healthScore = healthReportVo.getHealthAssessment().getHealthIndex();//健康评分（来自于AI结果）
        healthAssessment.setHealthScore(String.valueOf(healthScore));//健康评分（来自于AI结果）
        healthAssessment.setTotalCheckDate(healthReportVo.getTotalCheckDate());//总检日期
        healthAssessment.setRiskLevel(healthReportVo.getHealthAssessment().getRiskLevel());//危险等级
        healthAssessment.setReportSummary(healthReportVo.getSummarize());//报告总结
        healthAssessment.setDiseaseRisk(JSON.toJSONString(healthReportVo.getRiskDistribution()));//疾病风险
        healthAssessment.setAbnormalAnalysis(JSON.toJSONString(healthReportVo.getAbnormalData()));//异常分析
        healthAssessment.setSystemScore(JSON.toJSONString(healthReportVo.getSystemScore()));//健康系统分值
        healthAssessment.setSuggestionForAdmission(healthScore>=60?0:1);//是否建议入住(0:建议,1:不建议)
        healthAssessment.setNursingLevelName(getNursingLevelName(healthScore));//推荐护理等级
        healthAssessment.setAdmissionStatus(1);//入住情况 (0:已入住,1:未入住)
        healthAssessment.setAssessmentTime(LocalDateTime.now());//评估时间
        boolean result = this.save(healthAssessment);
        if(!result) {
            throw new BaseException("新增健康评估数据失败");
        }
        return healthAssessment.getId();
    }

    /**
     * 推荐护理等级判断方法
     * @param healthScore
     * @return
     */
    private String getNursingLevelName(double healthScore) {
        if (healthScore<0||healthScore>100){
            throw new BaseException("健康评分非法");
        }
        String levelName = "不建议入住";
        if (healthScore>=90){
            levelName="四级护理等级";
        } else if (healthScore>=80) {
            levelName="三级护理等级";
        } else if (healthScore>=70) {
            levelName="二级护理等级";
        } else if (healthScore>=60) {
            levelName="一级护理等级";
        }
        return levelName;
    }

    /**
     * 修改健康评估
     * 
     * @param healthAssessment 健康评估
     * @return 结果
     */
    @Override
    public int updateHealthAssessment(HealthAssessment healthAssessment)
    {
        return updateById(healthAssessment) ? 1 : 0;
    }

    /**
     * 批量删除健康评估
     * 
     * @param ids 需要删除的健康评估主键
     * @return 结果
     */
    @Override
    public int deleteHealthAssessmentByIds(Long[] ids)
    {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除健康评估信息
     * 
     * @param id 健康评估主键
     * @return 结果
     */
    @Override
    public int deleteHealthAssessmentById(Long id)
    {
        return removeById(id) ? 1 : 0;
    }
}
